#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/bio.h>

int main() {
    FILE *fp;
    EVP_PKEY *pkey;
    RSA *rsa;
    const BIGNUM *n, *e, *d;
    X509 *cert;

    // 打开私钥文件
    if ((fp = fopen("../../cert/rsa_server.key", "r")) == NULL) {
        perror("Failed to open private key file");
        exit(EXIT_FAILURE);
    }

    // 读取私钥
    if ((pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
        perror("Failed to read private key");
        exit(EXIT_FAILURE);
    }

    // 关闭文件
    fclose(fp);

    // 提取 RSA 私钥
    rsa = EVP_PKEY_get0_RSA(pkey);
    if (rsa == NULL) {
        perror("Failed to get RSA private key");
        exit(EXIT_FAILURE);
    }

    // 提取 RSA 私钥参数
    RSA_get0_key(rsa, &n, &e, &d);

    // 计算私钥长度（以字节为单位）
    int private_key_length_bytes = RSA_size(rsa);

    // 输出私钥长度
    printf("RSA Private Key Length: %d bytes\n", private_key_length_bytes);

    // 读取证书文件
    if ((fp = fopen("../../cert/rsa_server.pem", "r")) == NULL) {
        perror("Failed to open certificate file");
        exit(EXIT_FAILURE);
    }

    // 读取证书
    if ((cert = PEM_read_X509(fp, NULL, NULL, NULL)) == NULL) {
        perror("Failed to read certificate");
        exit(EXIT_FAILURE);
    }

    // 关闭文件
    fclose(fp);

    // 提取公钥
    EVP_PKEY *pubkey = X509_get_pubkey(cert);
    if (pubkey == NULL) {
        perror("Failed to get public key from certificate");
        exit(EXIT_FAILURE);
    }

    // 获取公钥的 RSA 结构
    RSA *pub_rsa = EVP_PKEY_get0_RSA(pubkey);
    if (pub_rsa == NULL) {
        perror("Failed to get RSA public key");
        exit(EXIT_FAILURE);
    }

    // 计算公钥长度（以字节为单位）
    int public_key_length_bytes = RSA_size(pub_rsa);

    // 输出公钥长度
    printf("RSA Public Key Length: %d bytes\n", public_key_length_bytes);

    unsigned char *der_pubkey = (unsigned char *)malloc(public_key_length_bytes * 2);

    unsigned char *der_pubkey_ptr = der_pubkey;
    i2d_PUBKEY(pubkey, &der_pubkey_ptr);
    printf("Public key:\n");
    BIO_dump_fp(stdout, der_pubkey, 550);

    // 释放资源
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(pubkey);
    X509_free(cert);

    return 0;
}

